HSTS(HTTP Strict Transport Security)
#memo #調べてみた #2020.11
https://ja.wikipedia.org/wiki/HTTP_Strict_Transport_Security
https://kinsta.com/jp/knowledgebase/hsts-strict-transport-security/
https://pisuke-code.com/htaccess-way-to-set-header/
https://labcoat.jp/hsts-preload/#62_8220htaccess8221HSTS_preload
https://re-means.com/always-ssl-of-describe-the-hsts-to-htaccess-how-to-register-to-hsts-preload-submission/
目的とゴール:上記サイトを読んでHSTSについてまとめて理解する。それと自分で設定して見て成功するかどうかやってみる。
https://hstspreload.org/
上記でhstsのpreloadのための登録ができるらしい。ただし削除は容易ではない、とのこと。
HSTSは中間者攻撃に対して有効
HSTS何もわからないので調べた
手始めにと思い、.htaccessについて曖昧だったので調べていく(サンプル使ってリライトを試しながら書いているとめちゃくちゃ長くなったので分けた)
HSTSについて
HSTSではユーザーがWebブラウザにスキームが httpであるURIを入力するなどしてHTTPで接続しようとした時に、予めWebサーバーが HSTSを有効にするよう指示してきたドメインの場合、Webブラウザが強制的にHTTPSでの接続に置き換えてアクセスすることで、この問題を解決する。
https://ja.wikipedia.org/wiki/HTTP_Strict_Transport_Security
ドメイン単位で、ブラウザに対して次回以降強制的にHTTPSで接続しにくるようにヘッダーを使って指示することができる。
とはいえ、最初にヘッダーを返すために接続してきたときはHTTPでの接続になりえてしまい、「それ結局セキュアじゃない」となるので、HSTS Preloadingという仕組みが存在する。
最初の接続ではWebブラウザはHTTPS接続を強制するべきかどうかを知り得ないため、攻撃に対して脆弱である。この問題に対する解決策として、HSTS Preloadingが存在する。
引用元同上
HSTSPreloadについては下記のサイトを読むとより実態がわかりやすい
例えホームページを常時SSL化したとしても、常時SSL化未対応だった頃の被リンクからの流入は、そのURLをhttpからhttpsに変えてもらわない限りhttpでの接続となります。また、URL直打ちでもhttp接続の恐れがありますね。従って、この設定によってhttp接続を全てhttpsへリダイレクトします。しかし、この設定では毎回一度はhttp接続してしまいます。
一方、HSTSは一度サイトを閲覧すれば2回目以降はhttpsに直接繋がるようになり、セキュリティが高まります。
では1回目はどうかと言うと、残念ながら一旦http接続されてしまいます。そこで、初回訪問時からhttpsに直接アクセスさせるための機能が、次に紹介するHSTS preload(HSTSプリロード)です。
https://labcoat.jp/hsts-preload/#62_8220htaccess8221HSTS_preload
HSTSプリロードリストとは 
HSTSのプリロードというものもあります。これは基本的に、ウェブサイトまたはドメインをブラウザーに組み込まれている承認済みのHSTSリストに登録する制度です。HSTSプリロードリストはGoogleにより作成され、Chrome、Firefox、Opera、Safari、IE11、およびEdgeで採用されています。
https://kinsta.com/jp/knowledgebase/hsts-strict-transport-security/
mochi5o.iconGoogleにより作成され..なるほど世界中のhttps接続して欲しいサイトをインデックスしていくのかすっげぃな
HSTS概要のまとめ
ヘッダーでブラウザに対してHTTPSを強制する + HSTS Preloading へドメイン単位で登録しておく
上記2つの仕組みにより安全性を担保するのがHSTSなので両方やっとかないと基本的に意味がない
ただしTLSが安全であるという前提で成り立ってるのでTLSの安全性がそもそも危なっかしいことになると担保されない(今のところ大丈夫)
ヘッダーの中身
具体的にはレスポンスヘッダーでは「Strict-Transport-Security」として表示される
下記はKinstaのサイト(最初のアクセスがstatus307だ)
https://gyazo.com/6a3924bac7f7628c20cce85c4ce19cfc
https://gyazo.com/e0917da692bd7fc64e6536cbc79b064a
301リダイレクトとどう違うの?なぜ.htaccessによるリライトではダメなのか?
Kinstaのサイトが詳しい
中間者攻撃については別途調べる
HSTSのヘッダー設定してみた
さて概要をまとめるのが目的ではなく、次こそ本題。
.htaccessでHSTSが有効にできるのかどうか。
ヘッダーが書き換わっていればOK。
これを見る限り、Apacheのリスタートとか書いてるけど?
https://pisuke-code.com/htaccess-way-to-set-header/
mod_headerのモジュールがサーバーで有効になっていさえすれば.htaccessからヘッダー書き換えれるぽい
ということでmod_headerモジュールが有効かどうかを調べる方法をググった
https://www.sppd.ne.jp/support/server/manual_htaccess.php
https://gyazo.com/213b59fa625e474bcdbe085ff319b206
上記サイトでヘッダーの編集方法が記載されているので、これを流用してヘッダー書き換えよう!
ドメインのルートの.htaccessを編集
code:header書き換え
$ cat .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on NC
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} R=301,L
</IfModule>
# ---追記ここから
<Files ~ "\.(cgi|php)$">
Header set Pragma no-cache
Header set Cache-Control "max-age=86400"
Header set Expires "Thu, 01 Dec 1994 16:00:00 GMT"
# この下だけ無効とかあったらいやだから他にも入れたけど、この下が必要な記述(本来はmax-age=1536000 1年がデフォ)
Header set Strict-Transport-Security "max-age=31; includeSubDomains; preload"
</Files>
$
https://www.mochi5o.work/blog/ では有効になった!
https://gyazo.com/d225e156ad742ac8d8ba5c3da65c75a9
けど、mochi5o.workだとヘッダー出なかった。なぜ?
<Files ~ "\.(cgi|php)$"> このディレクティブでcgiかphpの拡張子を指定してるからだ…
ということで修正 <Files ~ "\.(cgi|php|html)$">
書き換えると、無事に独自ドメインのルートでもヘッダー設定された!
別のヘッダーを書き換えたい目的のための記述を流用したので、ディレクティブとしてはファイルの名前の一致を使ってヘッダー書き換えたけど、もっと全部に対してやる方法はありそう。
ん?てかディレクティブなしとかでいいんじゃないか?
code:.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on NC
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} R=301,L
</IfModule>
<Files ~ "\.(cgi|php|html)$">
Header set Pragma no-cache
Header set Cache-Control "max-age=86400"
Header set Expires "Thu, 01 Dec 1994 16:00:00 GMT"
</Files>
Header set Strict-Transport-Security "max-age=31; includeSubDomains; preload"
このようにしてもStrict-Transport-Securityヘッダーは設定されていたので予想は正しい。全部に対して有効化しておくのがいいでしょう。
今回はHSTSプリロードについては設定しない。
設定方法はこのサイトがわかりやすい
https://labcoat.jp/hsts-preload/#62_8220htaccess8221HSTS_preload
設定途中で試しにmax-age=3とかで試しにやってみたところ、こんな感じでドメイン配下が全てHTTPSリダイレクトするようになっていないと怒られる(Warningの表示)
それとmax-age=1536000(=1年)にしていないとそもそもエラーで登録できない模様。一度間違って登録すると一年間設定消えないから厳しいな。。。サポートしづらい。
例えば証明書の期限切れとかが発生すると直ちにサイトが見れなくなってしまう。httpsへのリダイレクトをを強制するものなのでhttp〜の方残ってるから、みたいなのが一切できなくなる。
設定方法はこのサイトがわかりやすい
https://labcoat.jp/hsts-preload/#62_8220htaccess8221HSTS_preload
https://gyazo.com/e68a4040eba69001dc1c2a8045191c12